package com.helasasa.maxfunds.lineofcredit.cashloan.ghana.http

import android.content.Context
import android.os.Handler
import android.os.Looper
import com.helasasa.maxfunds.lineofcredit.cashloan.ProjectApplication
import com.helasasa.maxfunds.lineofcredit.cashloan.utils.analytics.util.AnalyticsUtil
import com.helasasa.maxfunds.lineofcredit.cashloan.utils.log.ApiLoggingInterceptor
import com.google.gson.Gson
import okhttp3.Call
import okhttp3.Callback
import okhttp3.ConnectionPool
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Protocol
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import org.json.JSONObject
import java.io.File
import java.io.IOException
import java.util.TimeZone
import java.util.concurrent.TimeUnit

/**
 * 初始化请求参数
 */
fun HashMap<String, Any>.createApiAction(): HashMap<String, Any> {
    apply {
        put("token", ProjectApplication.tkAction(true))
        put("userId", ProjectApplication.uidAction(true))
        put("version", ProjectApplication.mAppVersion)
        put("product", ProjectApplication.mProduct)
        put("channelCode", AnalyticsUtil.getInstallReferrer())
        put("subChannelCode", AnalyticsUtil.getInstallReferrer())
        put("clientType", "ANDROID")
        put("apiVersion", "v3")
        put("androidId", AnalyticsUtil.getAndroidId())
        put("advertId", AnalyticsUtil.getAdId())
        put("aduid", AnalyticsUtil.getAdId())
        put("aduidPath", AnalyticsUtil.getAndroidId())
        put("isLimitAdTrackingEnabled", AnalyticsUtil.getAdEnabled().toString())
    }
    return this
}

/**
 * 初始化请求参数
 */
fun HashMap<String, Any>.createZoneAction(): HashMap<String, Any> {
    apply {
        put("tz", TimeZone.getDefault().id.toString())
        put("p", ProjectApplication.mProduct.lowercase())
    }
    return this
}

/**
 * 判断是否是有效的action
 */
fun HashMap<String, Any>.isApiValidAction(): Boolean {
    if (containsKey("path")) {
        var path = (get("path") ?: "") as String
        if (path.startsWith("/")) {
            path = path.substring(1)
            put("path", path)
        }
        return path.isNotBlank()
    }
    return false
}

/**
 * 判断是否是有效的action
 */
fun HashMap<String, Any>.isImageUploadValidAction(): Boolean {
    if (containsKey("filePath")) {
        var path = (get("filePath") ?: "") as String
        return path.isNotBlank()
    }
    return false
}

/**
 * 生成RequestBody
 */
fun HashMap<String, Any>.toRequestBody(): RequestBody {
    // 加密前
    val content = Gson().toJson(this).trim()
    println("aes before：\n $content")

    // 加密后
    val encrypted: String = AESCryptUtil.encryptDefault(content)
    println("aes after：\n $encrypted")

    // 组装body
    val mediaType = "text/plain".toMediaTypeOrNull()
    return encrypted.toRequestBody(mediaType)
}

/**
 * 请求日志输出
 */
val apiLogginInterceptor: HttpLoggingInterceptor =
    HttpLoggingInterceptor(ApiLoggingInterceptor()).apply {
        this.level = HttpLoggingInterceptor.Level.BODY
    }

/**
 * 初始化请求域名
 */
const val apiHost = "https://www.helasasa.site" //"http://159.138.165.72"

/**
 * 公共加密路径
 */
const val apiCommonPath = "/VrImR015HqFp2y9elr0bIw" //"/v1/commonApi"

/**
 * 公共加密路径-zone
 */
const val apiZonePath = "/x4mxj1no08pm6xovwnhznta"

/**
 * 公共加密路径-上传图片
 */
const val apiImageUploadPath = "/DnVjqaXlIEC8lRZNZSPW0w"


/**
 * 拼接请求完整地址
 */
fun apiHostCombine(): String {
    var path = ProjectApplication.zonePathAction(true)
    if (path.startsWith("/")) {
        path = path.substring(1)
    }
    return "$apiHost/$path"
}

/**
 * 拼接请求完整地址
 */
fun apiHostCommonCombine(): String {
    return "${apiHostCombine()}$apiCommonPath"
}

/**
 * 拼接请求完整地址
 */
fun apiHostImageUploadCombine(): String {
    return "${apiHostCombine()}$apiImageUploadPath"
}

/**
 * 拼接请求完整地址
 */
fun apiHostZoneCombine(): String {
    return "$apiHost$apiZonePath"
}

/**
 * 请求客户端
 */
val apiClient = OkHttpClient.Builder()
    .connectTimeout(60, TimeUnit.SECONDS)
    .writeTimeout(60, TimeUnit.SECONDS)
    .readTimeout(60, TimeUnit.SECONDS)
    .retryOnConnectionFailure(true)
    .connectionPool(ConnectionPool(5, 3, TimeUnit.MINUTES))
    .protocols(listOf(Protocol.HTTP_1_1))
    .addNetworkInterceptor(apiLogginInterceptor)
    .build()

/**
 * 回调主线程
 */
val mainHandler = Handler(Looper.getMainLooper())

/**
 * http请求接口
 */
interface IApiProcessCallback {
    fun onApiReady()
    fun onApiDone(jsonObject: JSONObject)
    fun onApiError(code: String, errMsg: String)
}

/**
 * 进行post请求
 */
fun Context.doPostRequest(action: HashMap<String, Any>, callback: IApiProcessCallback?) {
    // 过滤请求是否有效
    if (!action.isApiValidAction()) return

    // 状态回调
    callback?.onApiReady()

    // 组装body
    val body: RequestBody = action.toRequestBody()

    // 目标地址
    val url = apiHostCommonCombine()

    // 构建POST请求
    val request = Request.Builder()
        .url(url)
        .post(body)
        .addHeader("Content-Type", "text/plain")
        .addHeader("Accept", "*/*")
        .addHeader("product", ProjectApplication.mProduct)
        .build()

    // 发送请求并处理响应
    apiClient.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            mainHandler.post {
                callback?.onApiError("9191", e.localizedMessage ?: "Request Error")
            }
        }

        override fun onResponse(call: Call, response: Response) {
            response.use {
                if (!it.isSuccessful) {
                    // 处理失败响应
                    println("Response: ${response.code}-${response.message}")
                    mainHandler.post {
                        callback?.onApiError("${response.code}", response.message)
                    }
                    return
                }

                // 处理成功响应的数据
                val responseData = response.body?.string()
                if (responseData == null) {
                    mainHandler.post {
                        callback?.onApiError("${response.code}", response.message)
                    }
                    return@use
                }

                val resJsonString = AESCryptUtil.decryptDefault(responseData)
                println("========path:${action["path"]}")
                try {
                    val resJsonObject = JSONObject(resJsonString)
                    val resCode = resJsonObject.optString("code", "-1").toInt()
                    val resMsg = resJsonObject.optString("msg")
                    if (resCode == 0) {
                        // 成功回调
                        mainHandler.post {
                            callback?.onApiDone(resJsonObject)
                        }
                    } else {
                        mainHandler.post {
                            callback?.onApiError("$resCode", resMsg)
                        }
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                    mainHandler.post {
                        callback?.onApiError("-2", e.localizedMessage ?: "Request Error")
                    }
                }
            }
        }
    })
}


/**
 * 进行post请求
 */
fun Context.doZoneRequest(action: HashMap<String, Any>, callback: IApiProcessCallback?) {
    // 状态回调
    callback?.onApiReady()

    // 组装body
    val body: RequestBody = action.toRequestBody()

    // 目标地址
    val url = apiHostZoneCombine()

    // 构建POST请求
    val request = Request.Builder()
        .url(url)
        .post(body)
        .addHeader("Content-Type", "text/plain")
        .addHeader("Accept", "*/*")
        .addHeader("product", ProjectApplication.mProduct)
        .build()

    // 发送请求并处理响应
    apiClient.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            mainHandler.post {
                callback?.onApiError("9191", e.localizedMessage ?: "Request Error")
            }
        }

        override fun onResponse(call: Call, response: Response) {
            response.use {
                if (!it.isSuccessful) {
                    // 处理失败响应
                    println("Response: ${response.code}-${response.message}")
                    mainHandler.post {
                        callback?.onApiError("${response.code}", response.message)
                    }
                    return
                }

                // 处理成功响应的数据
                val responseData = response.body?.string()
                if (responseData == null) {
                    mainHandler.post {
                        callback?.onApiError("${response.code}", response.message)
                    }
                    return@use
                }

                val resJsonString = AESCryptUtil.decryptDefault(responseData)
                try {
                    val resJsonObject = JSONObject(resJsonString)
                    val resCode = resJsonObject.optString("code", "-1").toInt()
                    val resMsg = resJsonObject.optString("msg")
                    if (resCode == 0) {
                        // 成功回调
                        mainHandler.post {
                            callback?.onApiDone(resJsonObject)
                        }
                    } else {
                        mainHandler.post {
                            callback?.onApiError("$resCode", resMsg)
                        }
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                    mainHandler.post {
                        callback?.onApiError("-2", e.localizedMessage ?: "Request Error")
                    }
                }
            }
        }
    })
}

/**
 * 进行图片上传
 */
fun Context.doUploadImage(action: HashMap<String, Any>, callback: IApiProcessCallback?) {
    // 过滤请求是否有效
    if (!action.isImageUploadValidAction()) return

    // 状态回调
    callback?.onApiReady()

    // 组装requestbody
    val filePath = action["filePath"] as String
    val file = File(filePath)
    val mediaType = if (filePath.endsWith(".png")) "image/png" else "image/jpg"
    val requestBody = file.asRequestBody(mediaType.toMediaTypeOrNull())

    // 组装body
    val body = MultipartBody.Builder()
        .setType(MultipartBody.FORM)
        .addFormDataPart("image", file.name, requestBody)
        .build()

    // 目标地址
    val url = apiHostImageUploadCombine()

    // 构建POST请求
    val request = Request.Builder()
        .url(url)
        .post(body)
        .addHeader("Accept", "*/*")
        .addHeader("product", ProjectApplication.mProduct)
        .build()

    // 发送请求并处理响应
    apiClient.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            mainHandler.post {
                callback?.onApiError("9191", e.localizedMessage ?: "Request Error")
            }
        }

        override fun onResponse(call: Call, response: Response) {
            response.use {
                if (!it.isSuccessful) {
                    // 处理失败响应
                    println("Response: ${response.code}-${response.message}")
                    mainHandler.post {
                        callback?.onApiError("${response.code}", response.message)
                    }
                    return
                }

                // 处理成功响应的数据
                val responseData = response.body?.string()
                if (responseData == null) {
                    mainHandler.post {
                        callback?.onApiError("${response.code}", response.message)
                    }
                    return@use
                }

                val resJsonObject = JSONObject(responseData)
                // 打印结果
                // ApiLoggingInterceptor.jsonLog(resJsonObject.toString())

                val resCode = resJsonObject.optString("code", "-1").toInt()
                val resMsg = resJsonObject.optString("msg")
                if (resCode == 0) {
                    // 成功回调
                    mainHandler.post {
                        // 回传cardtype
                        val obj = resJsonObject.optJSONObject("obj") ?: JSONObject()
                        val cardType = action["cardType"] as String
                        obj.put("cardType", cardType)
                        resJsonObject.put("obj", obj)
                        callback?.onApiDone(resJsonObject)
                    }
                } else {
                    mainHandler.post {
                        callback?.onApiError("$resCode", resMsg)
                    }
                }
            }
        }
    })
}

